home *** CD-ROM | disk | FTP | other *** search
/ ftp.cs.arizona.edu / ftp.cs.arizona.edu.tar / ftp.cs.arizona.edu / icon / newsgrp / group00b.txt / 000043_icon-group-sender _Tue Aug 22 07:39:52 2000.msg < prev    next >
Internet Message Format  |  2001-01-03  |  8KB

  1. Return-Path: <icon-group-sender>
  2. Received: (from root@localhost)
  3.     by baskerville.CS.Arizona.EDU (8.9.1a/8.9.1) id HAA13214
  4.     for icon-group-addresses; Tue, 22 Aug 2000 07:39:32 -0700 (MST)
  5. Message-Id: <200008221439.HAA13214@baskerville.CS.Arizona.EDU>
  6. Delivered-To: fixup-icon-group@CS.arizona.edu@fixme
  7. Date: Mon, 21 Aug 2000 20:12:46 -0600
  8. From: Cheyenne Wills <cheyenne_wills@uswest.net>
  9. X-Accept-Language: en
  10. To: icon-group@optima.CS.Arizona.EDU
  11. Subject: Re: [Icon][WinNT] external C functions.
  12. Errors-To: icon-group-errors@optima.CS.Arizona.EDU
  13. Status: RO
  14. Content-Length: 6815
  15.  
  16. This is a multi-part message in MIME format.
  17. --------------30657AAB585C0267D4C3A50B
  18. Content-Type: text/plain; charset=us-ascii
  19. Content-Transfer-Encoding: 7bit
  20.  
  21. Well.. here is some code that I hacked a long time ago to implement
  22. dynamically loaded functions for OS/2.  You might be able to hack at it
  23. to work under WinNT.  Basically your code was loaded into a DLL and the
  24. Icon runtime could call out to it..
  25.  
  26. Anyway... enjoy...
  27.  
  28. ---[fload.r]---
  29. --------------30657AAB585C0267D4C3A50B
  30. Content-Type: text/plain; charset=us-ascii;
  31.  name="fload.r"
  32. Content-Disposition: inline;
  33.  filename="fload.r"
  34. Content-Transfer-Encoding: 7bit
  35.  
  36. /*
  37.  * File: fload.r
  38.  *  Contents: loadfunc.
  39.  *
  40.  *  This file contains loadfunc(), the dynamic loading function for
  41.  *  Unix systems having the <dlfcn.h> interface.
  42.  *
  43.  *  from Icon:
  44.  *     p := loadfunc(filename, funcname)
  45.  *     p(arg1, arg2, ...)
  46.  *
  47.  *  in C:
  48.  *     int func(int argc, dptr argv)
  49.  *      return -1 for failure, 0 for success, >0 for error
  50.  *      argc is number of true args not including argv[0]
  51.  *      argv[0] is for return value; others are true args
  52.  */
  53.  
  54. #ifdef LoadFunc
  55.  
  56. #ifndef RTLD_LAZY    /* normally from <dlfcn.h> */
  57. #define RTLD_LAZY 1
  58. #endif                    /* RTLD_LAZY */
  59.  
  60. #ifdef FreeBSD
  61.  
  62. /* Sorry, no dlerror() on FreeBSD. Fake it. */
  63. char *dlerror(void)
  64. {
  65.     int no;
  66.  
  67.     if (0 == dlctl(NULL, DL_GETERRNO, &no))
  68.     return(strerror(no));
  69.     else
  70.     return(NULL);
  71. }
  72.  
  73. #endif                    /* __FreeBSD__ */
  74.  
  75. #if COMPILER
  76. int glue Params(( int argc, dptr dargv, dptr rslt, continuation succ_count));
  77. #else
  78. int glue Params(( int argc, dptr dargv) );
  79. #endif /* COMPILER */
  80.  
  81. #if OS2
  82. int makefunc Params((dptr d, char *name, void *funcptr));
  83. #else
  84. int makefunc    Params((dptr d, char *name, int (*func)() ));
  85. #endif /* OS2 */
  86.  
  87. "loadfunc(filename,funcname) - load C function dynamically."
  88.  
  89. function{0,1} loadfunc(filename,funcname)
  90.  
  91.    if !cnv:C_string(filename) then
  92.       runerr(103, filename)
  93.    if !cnv:C_string(funcname) then
  94.       runerr(103, funcname)
  95.  
  96.    abstract {
  97.       return proc
  98.       }
  99.    body
  100.       {
  101. #if OS2
  102.     unsigned long modhandle;
  103.     int rc;
  104.  
  105. #passthru int (* _System funcaddr)(int argc, dptr dargv);
  106.  
  107.     rc = _loadmod(filename,&modhandle);
  108.     if (rc) {
  109.     runerr(216);
  110.     }
  111.     rc = DosQueryProcAddr( modhandle, 0, funcname, &funcaddr );
  112.     if (rc) {
  113.     _freemod(modhandle);
  114.     runerr(216);
  115.     }
  116.     if (!makefunc(&result, funcname, (void *)funcaddr ) ) {
  117.     _freemod(modhandle);
  118.     runerr(305);
  119.     }
  120.     return result;
  121.     }
  122.  
  123. #else    /* OS2 */
  124.  
  125.       int (*func)();
  126.       static char *curfile;
  127.       static void *handle;
  128.       char errbuf[1000];
  129.  
  130.       /*
  131.        * Get a library handle, reusing it over successive calls.
  132.        */
  133.       if (!handle || !curfile || strcmp(filename, curfile) != 0) {
  134.      if (curfile)
  135.         free((pointer)curfile);    /* free the old file name */
  136.      curfile = salloc(filename);    /* save the new name */
  137.      handle = dlopen(filename, RTLD_LAZY);    /* get the handle */
  138.      }
  139.       /*
  140.        * Load the function.  Diagnose both library and function errors here.
  141.        */
  142.       if (handle)
  143.      func = (int (*)())dlsym(handle, funcname);
  144.       if (!handle || !func) {
  145.      fprintf(stderr, "\nloadfunc(\"%s\",\"%s\"): %s\n",
  146.         filename, funcname, dlerror());
  147.      runerr(216);
  148.      }
  149.       /*
  150.        * Build and return a proc descriptor.
  151.        */
  152.       if (!makefunc(&result, funcname, func))
  153.      runerr(305);
  154.       return result;
  155.       }
  156. #endif /* OS2 */
  157. end
  158.  
  159. /*
  160.  * makefunc(d, name, func) -- make function descriptor in d.
  161.  *
  162.  *  Returns 0 if memory could not be allocated.
  163.  */
  164. int makefunc(d, name, func)
  165. dptr d;
  166. char *name;
  167.  
  168. #if OS2
  169. void *func;
  170. #else
  171. int (*func)();
  172. #endif /* OS2 */
  173.  
  174.    {
  175.    struct b_proc *blk;
  176.  
  177.    blk = (struct b_proc *)malloc(sizeof(struct b_proc));
  178.    if (!blk)
  179.       return 0;
  180.    blk->title = T_Proc;
  181.    blk->blksize = sizeof(struct b_proc);
  182.  
  183. #if COMPILER
  184.    blk->ccode = glue;        /* set code addr to glue routine */
  185. #else                    /* COMPILER */
  186.    blk->entryp.ccode = glue;    /* set code addr to glue routine */
  187. #endif                    /* COMPILER */
  188.  
  189.    blk->nparam = -1;        /* varargs flag */
  190.    blk->ndynam = -1;        /* treat as built-in function */
  191.    blk->nstatic = 0;
  192.    blk->fstatic = 0;
  193.    blk->pname.dword = strlen(name);
  194.    blk->pname.vword.sptr = salloc(name);
  195.    blk->lnames[0].dword = 0;
  196.    blk->lnames[0].vword.sptr = (char *)func;
  197.                 /* save func addr in lnames[0] vword */
  198.    d->dword = D_Proc;        /* build proc descriptor */
  199.    d->vword.bptr = (union block *)blk;
  200.    return 1;
  201.    }
  202.  
  203. /*
  204.  * This glue routine is called when a loaded function is invoked.
  205.  * It digs the actual C code address out of the proc block, and calls that.
  206.  */
  207.  
  208. #if COMPILER
  209.  
  210. int glue(argc, dargv, rslt, succ_cont)
  211. int argc;
  212. dptr dargv;
  213. dptr rslt;
  214. continuation succ_cont;
  215.    {
  216.    int i, status, (*func)();
  217.    struct b_proc *blk;
  218.    struct descrip r;
  219.    tended struct descrip p;
  220.  
  221.    dargv--;                /* reset pointer to proc entry */
  222.    for (i = 0; i <= argc; i++)
  223.       deref(&dargv[i], &dargv[i]);    /* dereference args including proc */
  224.  
  225.    blk = (struct b_proc *)dargv[0].vword.bptr;    /* proc block address */
  226.    func = (int (*)())blk->lnames[0].vword.sptr; /* entry point address */
  227.  
  228.    p = dargv[0];            /* save proc for traceback */
  229.    dargv[0] = nulldesc;         /* set default return value */
  230.    status = (*func)(argc, dargv);    /* call func */
  231.  
  232.    if (status == 0) {
  233.       *rslt = dargv[0];
  234.       Return;                /* success */
  235.       }
  236.  
  237.    if (status < 0)
  238.       Fail;                /* failure */
  239.  
  240.    r = dargv[0];            /* save result value */
  241.    dargv[0] = p;            /* restore proc for traceback */
  242.    if (is:null(r))
  243.       RunErr(status, NULL);        /* error, no value */
  244.    RunErr(status, &r);            /* error, with value */
  245.    }
  246.  
  247. #else                        /* COMPILER */
  248.  
  249. int glue(argc, dargv)
  250. int argc;
  251. dptr dargv;
  252.    {
  253.    int status;
  254. #if OS2
  255.  
  256. #passthru   int (* _System func)(int argc, dptr dargv);
  257.    void *funcptr;
  258.  
  259. #else
  260.    int (*func)();
  261. #endif /* OS2 */
  262.    struct b_proc *blk;
  263.    struct descrip r;
  264.    tended struct descrip p;
  265.  
  266.    blk = (struct b_proc *)dargv[0].vword.bptr;    /* proc block address */
  267. #if OS2
  268.    funcptr = (void *)blk->lnames[0].vword.sptr; /* entry point address */
  269.    func = funcptr;
  270. #else
  271.    func = (int (*)())blk->lnames[0].vword.sptr; /* entry point address */
  272. #endif
  273.  
  274.    p = dargv[0];            /* save proc for traceback */
  275.    dargv[0] = nulldesc;         /* set default return value */
  276.    status = (*func)(argc, dargv);    /* call func */
  277.  
  278.    if (status == 0)
  279.       Return;                /* success */
  280.    if (status < 0)
  281.       Fail;                /* failure */
  282.  
  283.    r = dargv[0];            /* save result value */
  284.    dargv[0] = p;            /* restore proc for traceback */
  285.    if (is:null(r))
  286.       RunErr(status, NULL);        /* error, no value */
  287.    RunErr(status, &r);            /* error, with value */
  288.    }
  289.  
  290. #endif                        /* COMPILER */
  291.  
  292. #else                        /* LoadFunc */
  293. static char junk;            /* avoid empty module */
  294. #endif                        /* LoadFunc */
  295.  
  296. --------------30657AAB585C0267D4C3A50B--
  297.  
  298.  
  299.